import com.demo.controller.BookAdviceController;
import com.demo.controller.BookController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * BookBeans, BookController, BookAdviceController, Book, BookApp这五个类
 * 是为了说明 Bean 对象被修改的例子.
 * 以上问题的原因是因为 Bean 默认情况下是单例状态（singleton）
 * 在 Spring 中 Bean 的作⽤域默认也是 singleton 单例模式。
 * Bean 的 6 种作⽤域:
 * 1. singleton：单例作⽤域
 * 2. prototype：原型作⽤域（多例作⽤域）
 * 3. request：请求作⽤域
 * 4. session：回话作⽤域
 * 5. application：全局作⽤域
 * 6. websocket：HTTP WebSocket 作⽤域
 * 注意后 4 种状态是 Spring MVC 中的值，在普通的 Spring 项⽬中只有前两种.
 *
 * singleton:
 *      描述：该作⽤域下的Bean在IoC容器中只存在⼀个实例：获取Bean（即通过
 *      applicationContext.getBean等⽅法获取）及装配Bean（即通过@Autowired注⼊）都是同⼀个对象。
 *      场景：通常⽆状态的Bean使⽤该作⽤域。⽆状态表示Bean对象的属性状态不需要更新
 *      备注：Spring默认选择该作⽤域
 *
 * prototype:
 *      描述：每次对该作⽤域下的Bean的请求都会创建新的实例：获取Bean（即通过
 *      applicationContext.getBean等⽅法获取）及装配Bean（即通过@Autowired注⼊）都是新的对象实例。
 *      场景：通常有状态的Bean使⽤该作⽤域
 *
 * request:
 *      描述：每次http请求会创建新的Bean实例，类似于prototype
 *      场景：⼀次http的请求和响应的共享Bean
 *      备注：限定SpringMVC中使⽤
 *
 * session:
 *      描述：在⼀个http session中，定义⼀个Bean实例
 *      场景：⽤户回话的共享Bean, ⽐如：记录⼀个⽤户的登陆信息
 *      备注：限定SpringMVC中使⽤
 *
 * application:
 *      描述：在⼀个http servlet Context中，定义⼀个Bean实例
 *      场景：Web应⽤的上下⽂信息，⽐如：记录⼀个应⽤的共享信息
 *      备注：限定SpringMVC中使⽤
 *
 * websocket:
 *      描述：在⼀个HTTP WebSocket的⽣命周期中，定义⼀个Bean实例
 *      场景：WebSocket的每次会话中，保存了⼀个Map结构的头信息，将⽤来包裹客户端消息头。第⼀
 *      次初始化后，直到WebSocket结束都是同⼀个Bean。
 *      备注：限定Spring WebSocket中使⽤
 */

public class BookApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        BookController bc = context.getBean("bookController", BookController.class);
        BookAdviceController ba = context.getBean("bookAdviceController", BookAdviceController.class);

        bc.getBook();
        ba.getBook();
    }
}
